package city.spring.modules.medicalstation.medicationRecordDrug.controller;

import city.spring.modules.medicalstation.drugdepositDrugExt.entity.DrugdepositDrugExtEntity;
import city.spring.modules.medicalstation.drugdepositDrugExt.service.DrugdepositDrugExtService;
import city.spring.modules.medicalstation.medicationRecordDrug.entity.MedicationRecordDrugExtEntity;
import city.spring.modules.medicalstation.medicationRecordDrug.repository.MedicationRecordDrugExtRepository;
import city.spring.modules.medicalstation.medicationRecordDrug.service.MedicationRecordDrugExtService;
import city.spring.modules.medicalstation.medicationRecordDrug.vo.MedicationRecordDrugVO;
import city.spring.utils.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Controller：
 *
 * @author 谢金婷
 * @date 2020-10-23 16:07:51
 */
@RestController
@RequestMapping("/medication_record/{medicationrecordId}/drug")
public class MedicationRecordDrugExtController extends ApiController {
    private final MedicationRecordDrugExtService medicationRecordDrugExtService;
    private final MedicationRecordDrugExtRepository medicationRecordDrugExtRepository;
    private final DrugdepositDrugExtService drugdepositDrugExtService;
    /**
     * 实体类可排序字段
     */
    private final List<SFunction<MedicationRecordDrugExtEntity, ?>> entityOrderFields;

    public MedicationRecordDrugExtController(MedicationRecordDrugExtService medicationRecordDrugExtService, MedicationRecordDrugExtRepository medicationRecordDrugExtRepository, DrugdepositDrugExtService drugdepositDrugExtService) {
        this.medicationRecordDrugExtService = medicationRecordDrugExtService;
        this.medicationRecordDrugExtRepository = medicationRecordDrugExtRepository;
        this.drugdepositDrugExtService = drugdepositDrugExtService;
        entityOrderFields = new ArrayList<>();
        entityOrderFields.add(MedicationRecordDrugExtEntity::getId);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getMedicationrecordId);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getDrugdepositDrugId);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getDrugCode);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getRecorddate);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getMedicationTime);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getSpecifications);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getQuantity);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getGmtCreate);
        entityOrderFields.add(MedicationRecordDrugExtEntity::getGmtModified);
    }

    @ModelAttribute
    public void getMedicationrecordId(@PathVariable String medicationrecordId) {
        if (medicationrecordId == null) {
            throw new RuntimeException("用药记录ID必须不为空");
        }
        System.out.println("medicationrecordId" + medicationrecordId);
    }

    /**
     * 获取全部的 <strong></strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault Pageable pageable, MedicationRecordDrugExtEntity entity) {
        LambdaQueryChainWrapper<MedicationRecordDrugExtEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }

    //    /**
//     * 分页获取 <strong></strong> 列表
//     *
//     * @param pageable 分页参数信息
//     */
//    @GetMapping
//    public Object list(@PageableDefault Pageable pageable, MedicationRecordDrugExtEntity entity) {
//        LambdaQueryChainWrapper<MedicationRecordDrugExtEntity> lambdaQuery = buildLambdaQuery(entity);
//        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
//        Page<MedicationRecordDrugExtEntity> page = lambdaQuery.page(MyBatisUtils.toPage(pageable, false));
//        return success(page);
//    }
    @GetMapping
    public Object list(@PathVariable String medicationrecordId) {
        return success(medicationRecordDrugExtRepository.getRecordDrugs(medicationrecordId));
    }

    //    /**
//     * 获取一个 <strong></strong>
//     *
//     * @param id 主键ID
//     */
//    @GetMapping("{id}")
//    public Object info(@PathVariable String id) {
//        return success(medicationRecordDrugExtService.getById(id));
//    }
    @GetMapping("{extId}")
    public Object getInfo(@PathVariable String medicationrecordId, @PathVariable String extId) {
        return success(medicationRecordDrugExtRepository.getRecordDrug(medicationrecordId, extId));
    }

    //    /**
//     * 添加一个 <strong></strong>
//     *
//     * @param entity 修改后的信息
//     */
//    @PostMapping
//    public Object add(@RequestBody MedicationRecordDrugExtEntity entity) {
//        medicationRecordDrugExtService.saveMedicationRecordDrugExt(entity);
//
//        HttpHeaders headers = new HttpHeaders();
//        headers.add(HttpHeaders.LOCATION, String.valueOf(entity.getId()));
//        return new ResponseEntity<>(headers, HttpStatus.CREATED);
//    }
    @PostMapping
    public Object addAll(@PathVariable String medicationrecordId, @RequestBody List<MedicationRecordDrugExtEntity> drugs) {

        // 查出已有的数据
        List<MedicationRecordDrugVO> dbDrugs = medicationRecordDrugExtRepository.getRecordDrugs(medicationrecordId);
        // 数据库已经存在的班次列表
        Set<String> dbDrugIdsSet = dbDrugs.stream()
                .map(MedicationRecordDrugExtEntity::getDrugdepositDrugId)
                .collect(Collectors.toSet());
        // 过滤掉已经存在数据库的数据
        List<MedicationRecordDrugExtEntity> needSaveDrugs = drugs.stream()
                .filter(item -> {
                    item.setMedicationrecordId(medicationrecordId);
                    item.setRemainAmount(item.getRemainAmount().subtract(item.getQuantity()));
                    String drugdepositDrugId = item.getDrugdepositDrugId();
                    // 过滤出不存在数据库中的数据
                    return drugdepositDrugId != null && !dbDrugIdsSet.contains(drugdepositDrugId);
                }).collect(Collectors.toList());
        if (!needSaveDrugs.isEmpty()) {
            medicationRecordDrugExtService.saveOrUpdateBatch(needSaveDrugs);
        }

        // 进行一次用药记录，则相应减少该药品剩余用药数量
        List<MedicationRecordDrugVO> recordDrugs = medicationRecordDrugExtRepository.getRecordDrugs(medicationrecordId);
        recordDrugs.forEach(recordDrugVO -> {
            // 根据drugdepositDrugId查出drugdepositDrugExtEntity
            DrugdepositDrugExtEntity drugdepositDrugExtEntity = drugdepositDrugExtService.getById(recordDrugVO.getDrugdepositDrugId());
            System.out.println("drugdepositDrugExtEntity" + drugdepositDrugExtEntity);
            BigDecimal totalAmount = drugdepositDrugExtEntity.getTotalAmount() == null ? BigDecimal.ZERO : drugdepositDrugExtEntity.getTotalAmount();
            BigDecimal remainAmount = drugdepositDrugExtEntity.getRemainAmount() == null ? BigDecimal.ZERO : drugdepositDrugExtEntity.getRemainAmount();
            drugdepositDrugExtEntity.setRemainAmount(remainAmount.subtract(recordDrugVO.getQuantity()));
            drugdepositDrugExtService.lambdaUpdate()
                    .set(DrugdepositDrugExtEntity::getRemainAmount, drugdepositDrugExtEntity.getRemainAmount())
                    .eq(DrugdepositDrugExtEntity::getId, drugdepositDrugExtEntity.getId())
                    .update();
        });

        return success(null);
    }

    //    /**
//     * 修改一个 <strong></strong>
//     *
//     * @param id     主键ID
//     * @param entity 修改后的信息
//     */
//    @PutMapping("{id}")
//    public Object update(@PathVariable String id, @RequestBody MedicationRecordDrugExtEntity entity) {
//        entity.setId(id);
//        medicationRecordDrugExtService.updateMedicationRecordDrugExt(entity);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }
    @PutMapping("{extId}")
    public Object update(@PathVariable String medicationrecordId, @PathVariable String extId, @RequestBody MedicationRecordDrugExtEntity extEntity) {
        extEntity.setId(extId);
        extEntity.setMedicationrecordId(medicationrecordId);
        medicationRecordDrugExtService.updateMedicationRecordDrugExt(extEntity);
        return success(null);
    }

    /**
     * 删除一个 <strong></strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        medicationRecordDrugExtService.deleteMedicationRecordDrugExt(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 删除多个 <strong></strong>
     *
     * @param ids 主键ID列表
     */
    @DeleteMapping
    public Object deleteIds(@RequestBody List<String> ids) {
        medicationRecordDrugExtService.deleteMedicationRecordDrugExt(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<MedicationRecordDrugExtEntity> buildLambdaQuery(MedicationRecordDrugExtEntity entity) {
        LambdaQueryChainWrapper<MedicationRecordDrugExtEntity> lambdaQuery = medicationRecordDrugExtService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), MedicationRecordDrugExtEntity::getId, entity.getId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getMedicationrecordId()), MedicationRecordDrugExtEntity::getMedicationrecordId, entity.getMedicationrecordId());
        lambdaQuery.eq(entity.getDrugdepositDrugId() != null, MedicationRecordDrugExtEntity::getDrugdepositDrugId, entity.getDrugdepositDrugId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getDrugCode()), MedicationRecordDrugExtEntity::getDrugCode, entity.getDrugCode());
        lambdaQuery.eq(entity.getRecorddate() != null, MedicationRecordDrugExtEntity::getRecorddate, entity.getRecorddate());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getMedicationTime()), MedicationRecordDrugExtEntity::getMedicationTime, entity.getMedicationTime());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getSpecifications()), MedicationRecordDrugExtEntity::getSpecifications, entity.getSpecifications());
        lambdaQuery.eq(entity.getQuantity() != null, MedicationRecordDrugExtEntity::getQuantity, entity.getQuantity());
        lambdaQuery.eq(entity.getGmtCreate() != null, MedicationRecordDrugExtEntity::getGmtCreate, entity.getGmtCreate());
        lambdaQuery.eq(entity.getGmtModified() != null, MedicationRecordDrugExtEntity::getGmtModified, entity.getGmtModified());
        return lambdaQuery;
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private QueryWrapper<MedicationRecordDrugExtEntity> buildQuery(MedicationRecordDrugExtEntity entity) {
        QueryWrapper<MedicationRecordDrugExtEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(entity.getId()), "id", entity.getId());
        wrapper.like(StringUtils.isNotBlank(entity.getMedicationrecordId()), "medicationrecord_id", entity.getMedicationrecordId());
        wrapper.eq(entity.getDrugdepositDrugId() != null, "drugdeposit_drug_id", entity.getDrugdepositDrugId());
        wrapper.like(StringUtils.isNotBlank(entity.getDrugCode()), "drug_code", entity.getDrugCode());
        wrapper.eq(entity.getRecorddate() != null, "recorddate", entity.getRecorddate());
        wrapper.like(StringUtils.isNotBlank(entity.getMedicationTime()), "taketime", entity.getMedicationTime());
        wrapper.like(StringUtils.isNotBlank(entity.getSpecifications()), "minimum_specification", entity.getSpecifications());
        wrapper.eq(entity.getQuantity() != null, "quantity", entity.getQuantity());
        wrapper.eq(entity.getGmtCreate() != null, "gmt_create", entity.getGmtCreate());
        wrapper.eq(entity.getGmtModified() != null, "gmt_modified", entity.getGmtModified());
        return wrapper;
    }

}
